#ifndef DEFS_H
#define DEFS_H

#include <stdio.h>

#define REPORT_TYPE_USER_AGENT 1
#define REPORT_TYPE_HOST       2
#define REPORT_TYPE_URI        4

#define FLAG_TYPE_USER_AGENT "u"
#define FLAG_TYPE_HOST       "h"
#define FLAG_TYPE_URI        "i"

#define OUTPUT_FORMAT_HUMAN 1
#define OUTPUT_FORMAT_GREP  2
#define OUTPUT_FORMAT_XML   4
#define OUTPUT_FORMAT_CSV   8

#define FLAG_FORMAT_HUMAN "m"
#define FLAG_FORMAT_GREP  "g"
#define FLAG_FORMAT_XML   "x"
#define FLAG_FORMAT_CSV   "c"

#define FLAG_FILE_BASE    "f"

#define REQUEST_METHOD_GET    1
#define REQUEST_METHOD_POST   2
#define REQUEST_METHOD_PUT    4
#define REQUEST_METHOD_DELETE 8
#define REQUEST_METHOD_HEAD   16

#define BROWSER_IE 1;
#define BROWSER_FIREFOX 2;
#define BROWSER_CHROME 4;
#define BROWSER_SAFARI 8;
#define BROWSER_OTHER 16;

#define PATTERN_COMBINED_1 "^(?:(?<add_hosts>(?:\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})|unknown),\\s+)*"\
							"(?<host>(?:\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})|(?:-))\\s"\
							"(?<cilent_ip>(?:\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})|(?:-))\\s"\
							"(?<client_id>(?:\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})|(?:-))\\s"\
							"\\[(?<date_day>\\d{1,2})\\/(?<date_month>\\w*)\\/(?<date_year>\\d{1,4}):"\
							"(?<time_hour>\\d{1,2}):(?<time_minute>\\d{1,2}):(?<time_second>\\d{1,2})\\s(?<utc_offset>.*)\\]\\s\""\
							"(?<request_method>[A-Z]{3,})\\s(?<request_uri>.*?)\\s(?<request_type>HTTP\\/1.(?:0|1))\"\\s"\
							"(?<response_code>\\d{3})\\s(?<response_size>\\d*|-)\\s\""\
							"(?<referrer>.*?)\"\\s\"(?<user_agent>.*?)\"$"

#define PATTERN_COMBINED "^(?:(?<add_hosts>(?:[0-9.]+)|unknown),\\s+)*"\
							"(?<host>(?:[0-9.]+)|(?:-))\\s"\
							"(?<cilent_ip>(?:[0-9.]+)|(?:-))\\s"\
							"(?<client_id>(?:[0-9.]+)|(?:-))\\s"\
							"\\[(?<date_day>\\d{1,2})\\/(?<date_month>\\w*)\\/(?<date_year>\\d{1,4}):"\
							"(?<time_hour>\\d{1,2}):(?<time_minute>\\d{1,2}):(?<time_second>\\d{1,2})\\s(?<utc_offset>.*)\\]\\s\""\
							"(?<request_method>[A-Z]{3,})\\s(?<request_uri>.*?)\\s(?<request_type>HTTP\\/1.(?:0|1))\"\\s"\
							"(?<response_code>\\d{3})\\s(?<response_size>\\d*|-)\\s\""\
							"(?<referrer>.*?)\"\\s\"(?<user_agent>.*?)\"$"

#define PATTERN_COMBINED_OVEC_LEN 60

typedef struct settings {
	int report_types;        // report type options
	int output_format;       // output type options
	char * filename;         // filename to analyze
	char * column_delimiter; // the delimiter to use for reporting
} settings;

// setup a macro to define the default options for the program settings
#define DEFAULT_SETTINGS { REPORT_TYPE_USER_AGENT | REPORT_TYPE_HOST | REPORT_TYPE_URI, OUTPUT_FORMAT_HUMAN, "", " " }

typedef struct log_line {
	char * line_contents;    // raw contents of a line in the http log file
	int    line_length;      // the length of the line
} log_line;

typedef struct log_file {
	const char * log_file_path;      // the log file's path
	FILE *       log_file_pointer;   // the FILE pointer to the log file
} log_file;

typedef struct log_stats {
	int request_total;
	int request_failed;
	int request_success;
	unsigned long total_response_bytes;

} log_stats;

typedef struct parsed_log_entry {
	char * remote_host;       // the host portion of the log line
	char * local_host;        // local host
	char * client_identity;   // the (unreliable) client identity
	char * remote_user;       // the remote user (also unreliable)
	char * time;              // the time the last request was fulfilled
	char * request_string;    // the request uri
	char * request_uri;       // the requested URI
	char * user_agent;        // the user agent of the client
	int    request_method;    // the HTTP method that was used for this request
	int    status;
	int    response_size;
} parsed_log_entry;

#endif

